//package com.ht.config.dataAuth;
//
//import cn.hutool.core.collection.CollectionUtil;
//import cn.hutool.core.util.ObjectUtil;
//import com.ht.module.sys.service.sysRoleAuthService;
//import com.ht.module.sys.vo.SysRoleAuth.UserAuthVo;
//import com.ht.util.UserUtil;
//import lombok.SneakyThrows;
//
//import org.aopalliance.intercept.Interceptor;
//import org.aopalliance.intercept.Invocation;
//import org.apache.ibatis.executor.statement.StatementHandler;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.mapping.SqlCommandType;
//import org.apache.ibatis.plugin.Intercepts;
//import org.apache.ibatis.plugin.Plugin;
//import org.apache.ibatis.plugin.Signature;
//import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.reflection.SystemMetaObject;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.ApplicationContext;
//import org.springframework.stereotype.Component;
//
//import java.sql.Connection;
//import java.util.Map;
//import java.util.Properties;
//
//@Intercepts({
//        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
//})
//@Component
//public class DataScopeInterceptor implements Interceptor {
//    @Autowired
//    private ApplicationContext applicationContext;
//
//    @Override
//    @SneakyThrows
//    public Object intercept(Invocation invocation) {
//        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
//        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
//
//        // 获取 MappedStatement 判断是不是 SELECT
//        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
//        if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
//            return invocation.proceed();
//        }
//
//        BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
//        Object parameterObject = boundSql.getParameterObject();
//
//        // 查找是否包含 DataScope 参数
//        DataScope dataScope = findDataScopeObject(parameterObject);
//        if (dataScope == null) {
//            return invocation.proceed();
//        }
//
//        String oldSQL = boundSql.getSql();
//        StringBuilder newSQL = new StringBuilder();
//        if (oldSQL.startsWith("SELECT COUNT")) {
//            newSQL = new StringBuilder(oldSQL);
//        }else{
//            newSQL = new StringBuilder("SELECT * FROM (").append(oldSQL).append(") TOTAL");
//        }
//        // 获取当前登录用户权限
//        sysRoleAuthService sysRoleAuthService = applicationContext.getBean(sysRoleAuthService.class);
//        UserAuthVo vo = sysRoleAuthService.findByUserId(UserUtil.getUserId());
//
//        if (ObjectUtil.isNotEmpty(vo.getDeptIds()) && !vo.getDeptIds().isEmpty()) {
//            newSQL.append(" WHERE TOTAL.")
//                    .append(dataScope.getScopeName())
//                    .append(" IN ('").append(CollectionUtil.join(vo.getDeptIds(), "','")).append("')");
//
//            newSQL.append(" OR TOTAL.")
//                    .append(dataScope.getScopeUser())
//                    .append(" IN ('").append(CollectionUtil.join(vo.getUserIds(), "','")).append("')");
//        } else {
//            newSQL.append(" WHERE 1 = 0");
//        }
//
//        // 修改 SQL
//        metaObject.setValue("delegate.boundSql.sql", newSQL.toString());
//        return invocation.proceed();
//    }
//
//    @Override
//    public Object plugin(Object target) {
//        if (target instanceof StatementHandler) {
//            return Plugin.wrap(target, this);
//        }
//        return target;
//    }
//
//    @Override
//    public void setProperties(Properties properties) {
//        // 可扩展
//    }
//
//    private DataScope findDataScopeObject(Object parameterObj) {
//        if (parameterObj instanceof DataScope) {
//            return (DataScope) parameterObj;
//        } else if (parameterObj instanceof Map) {
//            for (Object val : ((Map<?, ?>) parameterObj).values()) {
//                if (val instanceof DataScope) {
//                    return (DataScope) val;
//                }
//            }
//        }
//        return null;
//    }
//
//}
